package com.can.config;


import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

//AOP:拦截器
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    //链式编程

    //授权
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //首页所有人可以访问,功能页只有对应有权限的人才能访问
        //请求授权的规则~
        http.authorizeRequests()
                .antMatchers("/").permitAll() //所有人都可以访问"/"
                .antMatchers("/level1/**").hasRole("vip1") //vip1角色才能访问 /level1/**
                .antMatchers("/level2/**").hasRole("vip2") //vip2角色才能访问 /level2/**
                .antMatchers("/level3/**").hasRole("vip3") //vip3角色才能访问 /level3/**
        ;

        //没有权限默认会到登入页面,需要开启的登入的页面。
        // 认证页面"/Login" 认证失败页面"/login?error"
        //loginPage:定制登录页面 ,原来的默认"/login"失效
        //From表单登录请求 默认也是跟登录页面同样的请求 也可以loginProcessingUrl自定义登录请求Url
        //默认的账号和密码name是 "username"和"password"，usernameParameter/passwordParameter可以自定义name值
        http.formLogin().loginPage("/toLogin").loginProcessingUrl("/login")
                .usernameParameter("user").passwordParameter("pwd");

        //注销,开启了注销功能
        //注销会请求/logout  注销成功会重定向到/login?logout
        //deleteCookies可以删除Cookies  LogoutUrl可以自定义地址
        //http.logout().deleteCookies("remove").invalidateHttpSession(true);//true:清空所有的session
        //http.logout().logoutUrl("/");
        http.logout().logoutSuccessUrl("/");//注销成功重定向到首页


        //防止网站攻击：get ,post
        http.csrf().disable();//关闭csrf功能  防止跨站请求(springboot默认会开启)

        //开启记住我功能 cookie和session实现 默认保存两周(14天),.rememberMeParameter自定义 "记住我标签" 参数是前端的name值
        http.rememberMe().rememberMeParameter("remember");

    }

    //认证，springboot 2.1.x 可以直接使用~
    //密码编码：PasswordEncoder   BCryptPasswordEncoder
    //在spring Security 5.0+ 新增了很多加密方法~ BCryptPasswordEncoder
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //在内存中的添加用户权限验证
        //这些数据正常应该从数据库中读取
        //添加用户
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder()) //需要BCryptPasswordEncoder密码转码才行
                .withUser("can").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2")
                .and()
                .withUser("root").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1","vip2","vip3")
                .and()
                .withUser("guest").password(new BCryptPasswordEncoder().encode("123456")).roles("vip1")
        ;
    }
}
